home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / c_lib.arc / PCSHRINK.C < prev    next >
Text File  |  1990-08-09  |  5KB  |  135 lines

  1. /**
  2. *
  3. *  Name         pcshrink -- Release all memory not needed but allocated
  4. *               by DOS when the program is loaded.
  5. *
  6. *  Synopsis     ercode = pcshrink(psize);
  7. *               int ercode        Return code from DOS function call
  8. *               unsigned *psize   Memory size of the program in paragraphs
  9. *                                 after unused memory is released.
  10. *
  11. *  Description  When DOS loads a program, all available memory is
  12. *               allocated to it.  PCSHRINK releases the memory beyond the
  13. *               program memory returning it to the free memory pool.
  14. *               The memory block is altered by making a call to PCSETBLK;
  15. *               the segment address of the block is given by the program
  16. *               segment prefix. The adjusted size is the code size plus
  17. *               the data size.  For large data memory models, there may
  18. *               no available memory if the stack and heap use all available
  19. *               memory.
  20. *
  21. *  Returns      ercode            Error code returned from the call to
  22. *                                 PCSETBLK.
  23. *               psize             Size of the memory block allocated to
  24. *                                 program in paragraphs.
  25. *
  26. *  Version      1.1  (C)Copyright Blaise Computing Inc.  1983, 1984
  27. *
  28. **/
  29. #include <compiler.h>
  30.  
  31. #define min(a,b)        ((a)<=(b)?(a):(b))
  32.  
  33. struct segads                          /* Offset, segment address type */
  34. {
  35.   unsigned r;
  36.   unsigned s;
  37. };
  38. #define ADS     struct segads          /* Abbreviation                 */
  39.  
  40. #if LAT200
  41. extern ADS _psp;                       /* Program segment prefix       */
  42. extern unsigned _top;                  /* Top of stack relative to SS  */
  43. #endif
  44. #if CI201A
  45. extern ADS _pspseg;
  46. #endif
  47. #if LAT104
  48. extern unsigned _pgmseg;
  49. extern unsigned _top;                  /* Number of bytes in data seg  */
  50. #endif
  51. #if CI133D
  52. extern unsigned _pgmseg;
  53. #endif
  54.  
  55. int pcshrink(psize)
  56. unsigned *psize;
  57. {
  58.  
  59.     unsigned code_size,data_size;
  60.     unsigned size;                     /* Request size of prog block   */
  61.     unsigned cs,ss,ds,es;              /* Segment register values      */
  62.     ADS      ptopmem,topmem_ads;
  63.     unsigned topmem;                   /* Top of memory                */
  64. #if CI201A & LDATA
  65.     unsigned long ptrtoabs();
  66. #endif
  67.     unsigned seg;
  68.     int      utslmove();
  69.  
  70. #if LAT104 | CI133D
  71.     ptopmem.s = _pgmseg;               /* Top of memory size is at     */
  72. #endif                                 /* offset 2 of the program      */
  73. #if LAT200                             /* segment prefix.              */
  74.     ptopmem.s = _psp.s;
  75. #endif
  76. #if CI201A
  77.     ptopmem.s = _pspseg.s;
  78. #endif
  79.     ptopmem.r = 2;
  80. #if LDATA
  81. #if CI201A
  82.     topmem_ads.s = (unsigned)((ptrtoabs(&topmem) & 0xffff0L) >> 4L);
  83.     topmem_ads.r = (unsigned)(ptrtoabs(&topmem) & 0xfL);
  84. #else
  85.     topmem_ads.s = (unsigned)(((long)(&topmem) & 0xffff0L) >> 4L);
  86.     topmem_ads.r = (unsigned)((long)(&topmem) & 0xfL);
  87. #endif
  88. #else
  89.     utsreg(&cs,&ss,&ds,&es);           /* Return segment reg values    */
  90.     topmem_ads.s = ds;
  91.     topmem_ads.r = &topmem;
  92. #endif
  93.     utslmove(&ptopmem,&topmem_ads,2);
  94.  
  95. #if LAT104
  96.     code_size   = ds - _pgmseg;        /* code size is DS - PSP        */
  97.     data_size   = _top/16 + 1;         /* data size in paragraphs      */
  98.     size        = code_size + data_size;
  99.     return(pcsetblk(_pgmseg,size,psize));
  100. #endif
  101.  
  102. #if LAT200
  103. #if LDATA
  104.     size    = topmem - _psp.s;
  105.     *psize  = size;                    /* All of memory is used       */
  106.     return(0);
  107. #else
  108.     code_size   = ds - _psp.s;         /* code size is DS - PSP        */
  109.     data_size   = _top/16 + 1;         /* data size in paragraphs      */
  110.     size        = code_size + data_size;
  111.     return(pcsetblk(_psp.s,size,psize));
  112. #endif
  113. #endif
  114.  
  115. #if CI133D
  116.     data_size = min(topmem - ss,0x1000);  /* The data size is the min */
  117.     code_size = ds - _pgmseg;             /* of 0x1000 (64K) and the  */
  118.     size      = data_size + code_size;    /* data segment size.       */
  119.     return(pcsetblk(_pgmseg,size,psize));
  120. #endif
  121.  
  122. #if CI201A
  123.     /* The C86 Optimizing compiler frees up all available memory at    */
  124.     /* initiation, so pcsetblk need not be called.  To return the size */
  125.     /* of the program, we compute how much free memory is left and     */
  126.     /* subtract that from the difference of top of memory and the Pro- */
  127.     /* gram Segment Prefix.                                            */
  128.  
  129.     pcalloc(0xffff,&seg,psize);
  130.     *psize = (topmem - _pspseg.s) - *psize;
  131.     return(0);
  132. #endif
  133.  
  134. }
  135.